Skip to content

feat: add Java dynamic dedup agent#181

Open
officialasishkumar wants to merge 14 commits intomainfrom
codex/java-dynamic-dedup
Open

feat: add Java dynamic dedup agent#181
officialasishkumar wants to merge 14 commits intomainfrom
codex/java-dynamic-dedup

Conversation

@officialasishkumar
Copy link
Copy Markdown
Member

@officialasishkumar officialasishkumar commented Apr 25, 2026

Supersedes #180 (re-opened from keploy/java-sdk so the head ref lives in this repo instead of the fork).

Related Issue

  • keploy/enterprise#1920

Related PRs

Closes: NA

Describe the changes you've made

Rewrites the Java SDK repo to be dedup-only. The old record/test/grpc/integration SDK modules are deleted; the remaining published module is keploy-sdk for Java dynamic dedup replay support.

  • Adds KeployDedupAgent for Enterprise dynamic dedup using /tmp/coverage_control.sock and /tmp/coverage_data.sock.
  • Handles per-testcase START <test-set>/<test-id> by resetting JaCoCo counters.
  • Handles matching END <test-set>/<test-id> by dumping/resetting JaCoCo execution data, analyzing app classes, publishing {id, executedLinesByFile}, and ACKing Enterprise.
  • Reads JaCoCo coverage in-process via the runtime API (org.jacoco.agent.rt.RT.getAgent().getExecutionData(...)) using reflection, so consumers do not need JaCoCo TCP server mode or --pass-through-ports.
  • Falls back to JaCoCo TCP server mode when the runtime API is unavailable; KEPLOY_JACOCO_HOST and KEPLOY_JACOCO_PORT still configure that fallback.
  • Discovers executable Spring Boot/fat jars from sun.java.command, which fixes Docker layouts where java.class.path does not include the runnable jar.
  • Keeps replay fast by caching class metadata, prioritizing explicit class dirs, and avoiding broad classpath fallback unless KEPLOY_JAVA_CLASSPATH_FALLBACK=true is set.
  • Keeps the servlet middleware only as a lifecycle hook for javax.servlet; Jakarta/Spring Boot 3 and non-servlet apps can call KeployDedupAgent.start() directly.
  • Updates the README to describe native, Docker, restricted Docker, and socket requirements for dedup-only usage.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Code style update (formatting, local variables)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How did you test your code changes?

  • mvn -B -DskipTests clean verify -pl keploy-sdk -am on JDK 8.
  • mvn -B -DskipTests clean verify -pl keploy-sdk -am on JDK 17.
  • mvn -B -DskipTests clean verify -pl keploy-sdk -am on JDK 21.
  • mvn -B -DskipTests -Dgpg.skip=true clean install -pl keploy-sdk -am for the local sample app build.
  • git diff --check.
  • Validated with samples-java/java-dedup against 1000 committed replay fixtures in Docker Compose: 1000 successes, 0 failures.
  • Validated with samples-java/java-dedup against 1000 committed replay fixtures in direct docker run: 1000 successes, 0 failures.
  • Confirmed keploy dedup --path . produced 982 duplicates and 18 retained tests.

No unit tests were added by request; validation is build and replay coverage.

Describe if there is any unusual behaviour of your code(Write NA if there isn't)

Java dedup attaches the JaCoCo Java agent and reads coverage in-process by default. If the in-process API cannot be located, the SDK falls back to JaCoCo's TCP server mode automatically. Docker and restricted Docker modes still require Enterprise and application containers/processes to share /tmp so the control/data Unix sockets are visible.

Checklist:

  • My code follows the style guidelines of this project.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas and used java doc.
  • I have made corresponding changes to the documentation.
  • My changes generate no new warnings.
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes.

Screenshots (if any)

NA

Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
- Use org.jacoco.agent.rt.RT.getAgent() to dump coverage in-process
  via reflection so the SDK does not depend on the runtime classifier
  at build time.
- Cache the resolved agent and fall back to TCP server mode if the
  runtime API is unavailable, preserving KEPLOY_JACOCO_HOST and
  KEPLOY_JACOCO_PORT for explicit overrides.
- Remove the requirement to launch JaCoCo in tcpserver mode and pass
  --pass-through-ports for the JaCoCo port; the in-process API
  bypasses Keploy's network proxy entirely.
- Update README to reflect the simpler default and document the TCP
  fallback path.

Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
- Adds .woodpecker/build.yml with parallel JDK 8, 17, and 21 builds
  using maven:3.9-eclipse-temurin-N images.
- Removes .github/workflows/maven.yml (single JDK 17 check).
- Matrix catches accidental newer-JDK API usage that the source/target
  1.8 setting alone does not enforce, and validates the JaCoCo runtime
  API and junixsocket native loading on every supported JDK.

Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
- Adds .woodpecker/release.yml that fires on tags matching v*.
- Imports the GPG private key, writes ~/.m2/settings.xml that pulls
  Sonatype credentials from environment variables, derives the artifact
  version by stripping the leading 'v' from the tag, and runs
  `mvn -P release clean deploy` to publish to Maven Central via the
  existing nexus-staging-maven-plugin (autoReleaseAfterClose=true).
- End users release with `git tag v2.0.0 && git push origin v2.0.0`.
- Requires Woodpecker secrets: maven_gpg_private_key,
  maven_gpg_passphrase, ossrh_username, ossrh_password.

Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
- Replaces the placeholder N.N.N version in the README install snippet
  with the upcoming 2.0.0 release tag, so end users can copy-paste the
  dependency block directly into their pom.xml after we publish.

Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants